package com.exp.bookhouse.controller.admin;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.exp.bookhouse.pojo.MyUser;
import com.exp.bookhouse.pojo.Role;
import com.exp.bookhouse.pojo.vo.UserDetailVo;
import com.exp.bookhouse.service.RoleService;
import com.exp.bookhouse.service.UserService;
import com.exp.bookhouse.util.Base64DecodeMultipartFile;
import com.exp.bookhouse.util.DateUtil;
import com.exp.bookhouse.util.TCaptchaVerify;
import io.swagger.annotations.*;
import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(value = "用户管理接口",tags = "管理员管理用户操作")
@Controller
@RequestMapping("/admin")
public class UserControllerAdmin {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @ApiOperation(value = "分页查询用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "p", value = "页数", required = false, dataType = "Int"),
            @ApiImplicitParam(paramType = "query", name = "s", value = "显示记录数", required = false, dataType = "Int"),
    })
    @GetMapping("/toUser")
    public String toUser(@RequestParam(value = "p",required = false,defaultValue = "1")Integer page,
                         @RequestParam(value = "s",required = false,defaultValue ="5")Integer size,
                         Model model){
        IPage<MyUser> iPage = userService.queryUserByPage(page,size);
        model.addAttribute("iPage",iPage);
        return "user";
    }

    @GetMapping("/toLogin")
    public String toLogin(){
        return "login";
    }

    @GetMapping("/toRegister")
    public String toRegister(){return "register";}

    @GetMapping("/toSaveUser")
    public String toSaveUser(){
        return "userAdd";
    }



    @ApiOperation(value = "查询用户可以添加的角色")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "用户id", required = true, dataType = "Long")
    })
    @GetMapping("/toUserAddRole/{id}")
    public String toUserAddRole(@PathVariable("id")Long userId, Model model){
        List<Role> roles = userService.queryOtherRoles(userId);
        model.addAttribute("userId",userId);
        model.addAttribute("roles",roles);
        return "userAddRole";
    }


    @ApiOperation(value = "添加用户角色")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", name = "userId", value = "用户id", required = true, dataType = "Long"),
            @ApiImplicitParam(paramType = "form", name = "ids", value = "用户id", required = true, allowMultiple = true, dataType = "String")
    })
    @PostMapping("/saveUserAddRole")
    public String saveUserAddRole(@RequestParam("userId")Long userId, @RequestParam("ids")String[] roleIds){
        userService.saveUserAddRole(userId,roleIds);
        return "redirect:/admin/toUser";
    }

    @ApiOperation(value = "查询用户角色详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "编号", required = true,dataType = "Long"),
            @ApiImplicitParam(paramType = "query", name = "p", value = "页码", required = true,dataType = "Int"),
            @ApiImplicitParam(paramType = "query", name = "s", value = "页数", required = true,dataType = "Int")
    })
    @GetMapping("/queryUserDetail/{id}/{p}/{s}")
    public String queryUserDetail(@PathVariable("id")Long id, @PathVariable("p")Integer page, @PathVariable("s")Integer size, Model model){
        IPage<Role> iPage = roleService.queryRolesByUserIdAndPage(id,page,size);
        MyUser myUser = userService.queryUserById(id);
        UserDetailVo userDetailVo = new UserDetailVo();
        userDetailVo.setMyUser(myUser);
        userDetailVo.setiPage(iPage);
        model.addAttribute("userDetailVo",userDetailVo);
        return "userDetail";
    }


//    @PostMapping("/login")
//    @ApiOperation(value = "登录")
//    @ApiImplicitParams({
//            @ApiImplicitParam(paramType = "query", name = "username", value = "用户名", required = true,dataType = "String"),
//            @ApiImplicitParam(paramType = "query", name = "password", value = "密码", required = true,dataType = "String")
//    })
//    public String login(@RequestParam("username")String username, @RequestParam("password")String password,
//                        @RequestParam(value = "rememberMe",required = false, defaultValue = "false")Boolean rememberMe,
//                        Model model){
//        //1.获取当前用户对象
//        Subject currentUser = SecurityUtils.getSubject();
//        //2.封装当前用户和密码为token
//        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//
//        try{
//            //3.执行登录操作
//            token.setRememberMe(rememberMe);
//            currentUser.login(token);  //如果没有异常说明登录成功
//
//            return "redirect:/admin/toIndex";		//登录成功，跳转首页
//        }catch (UnknownAccountException e){
//            model.addAttribute("msg","用户名错误");
////            model.addAttribute("msg","用户名或密码错误");
//            return "login";		//登录失败，跳转登录页
//        }catch (IncorrectCredentialsException e){
//            model.addAttribute("msg","密码错误");
////            model.addAttribute("msg","用户名或密码错误");
//            return "login";		//登录失败，跳转登录页
//        }catch (LockedAccountException e){
//            model.addAttribute("msg","用户名："+token.getPrincipal()+"被锁定，请联系管理员解锁");
//            return "login";		//登录失败，跳转登录页
//        }
//    }

    @RequestMapping("/login")
    public String login() {
        //这里什么都不错，由Spring Security负责登录验证
        return "/login";
    }

    @RequestMapping("/loginFail")
    public String loginFail() {
        //登录错误
        return "loginFail";
    }

    @ApiOperation(value = "注册用户")
    @PostMapping("/register")
//    @RequestMapping("/toRegister")
    public String register(@ApiParam(value = "用户信息",required = true) MyUser myUser) {
        userService.register(myUser);
        return "redirect:/admin/login";
    }

    /**
     * 退出
     * @param
     * @return
     */
//    @GetMapping("/logout")
//    public String logout(){
//        Subject subject = SecurityUtils.getSubject();
//        if (subject.isAuthenticated()) {
//            subject.logout(); // session 会销毁，在sessionlistener监听session销毁，清理权限缓存
//        }
//        return "login";
//    }
    @RequestMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        //获得用户认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            //注销
            new SecurityContextLogoutHandler().logout(request, response, authentication);
        }
        return "redirect:/login?logout";
    }


    @ApiOperation(value = "添加用户")
    @PostMapping("/saveUser")
    public String saveUser(@ApiParam(value = "用户信息",required = true) MyUser myUser, @ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) throws Exception {
        userService.saveUser(myUser, file);
        return "redirect:/admin/toUser";
    }


    @ApiOperation(value = "查询用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "用户id", required = true, dataType = "Long")
    })
    @GetMapping("/toUpdateUser/{id}")
    public String toUpdateUser(@PathVariable("id")Long id, Model model){
        MyUser myUser = userService.queryUserById(id);
        model.addAttribute("myUser", myUser);
        return "userUpdate";
    }

    @ApiOperation(value = "更新用户")
    @PostMapping("/updateUser")
    public String updateUser(@ApiParam(value = "用户信息",required = true) MyUser myUser, @ApiParam(value = "用户头像文件",required = true) @RequestParam("file") MultipartFile file) throws IOException {
        userService.updateUser(myUser,file);
        return "redirect:/admin/toUser";
    }

    @ApiOperation(value = "删除用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "用户id", required = true, dataType = "Long")
    })
    @GetMapping("/deleteUser/{id}")
    public String deleteUser(@PathVariable("id")Long id){
        userService.deleteUser(id);
        return "redirect:/admin/toUser";
    }


    @GetMapping("/toProfile")
    public String toProfile(Model model){
        String loginUser = SecurityContextHolder.getContext().getAuthentication().getName();//获取当前用户名称
        MyUser myUser = userService.queryUserByLoginName(loginUser);//获取当前用户对象
        myUser.setPassword(null);
        model.addAttribute("myUser", myUser);
        return "profile";
    }

    @ApiOperation(value = "更新用户头像")
    @PostMapping("/changeAvatar")
    public @ResponseBody
    Map<String,Object> changeAvatar(@ApiParam(value = "头像url",required = true) @RequestBody String avatar, Model model) throws Exception {
        String loginUser = SecurityContextHolder.getContext().getAuthentication().getName();//获取当前用户名称
        MyUser myUser = userService.queryUserByLoginName(loginUser);//获取当前用户对象
        String decode = URLDecoder.decode(avatar);
        MultipartFile file = Base64DecodeMultipartFile.base64Convert(decode);//base64转multipartFile
        String url = userService.changeAvatar(file, myUser.getId());
        myUser.setHeadImage(url);
        model.addAttribute("user", myUser);
        HashMap<String, Object> map = new HashMap<>();
        map.put("url",url);
        return map;
    }

    @ApiOperation(value = "按用户名查找用户")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", name = "userName", value = "用户姓名", required = true, dataType = "String"),
    })
    @PostMapping("/searchUser")
    public String searchUser(@RequestParam("userName")String userName,Model model){
        List<MyUser> iPage = userService.searchByUserName(userName);//根据用户姓名查找用户
        model.addAttribute("iPage",iPage);
        return "userSearchResult";
    }


    @PostMapping("/check")
    @ResponseBody
    public int check(@RequestParam("ticket") String ticket,
                     @RequestParam("randstr") String randstr){
        //防水墙验证
        return TCaptchaVerify.verifyTicket(ticket,randstr);
    }

    @ApiOperation(value = "导出用户列表")
    @RequestMapping("/exportUser")
    @ResponseBody
    public int exportUser() {
        List<MyUser> users = new ArrayList<>();
        users = userService.queryAllUser();
        return exportExcelPaper(users);
    }
    public int exportExcelPaper(List<MyUser> lists) {
        // 标题
        String[] title = { "账号", "姓名", "密码", "电话", "地址", "邮箱","更新时间"};
        // 创建一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 创建一个工作表sheet
        HSSFSheet sheet = workbook.createSheet();
        // 设置列宽
        setColumnWidth(sheet, 8);
        // 创建第一行
        HSSFRow row = sheet.createRow(0);
        // 创建一个单元格
        HSSFCell cell = null;
        // 创建表头
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            // 设置样式
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            // 设置字体
            HSSFFont font = workbook.createFont();
            font.setFontName("宋体");
            // font.setFontHeight((short)12);
            font.setFontHeightInPoints((short) 13);
            cellStyle.setFont(font);
            cell.setCellStyle(cellStyle);

            cell.setCellValue(title[i]);
        }
        // 从第二行开始追加数据
        for (int i = 1; i < (lists.size() + 1); i++) {
            // 创建第i行
            HSSFRow nextRow = sheet.createRow(i);
            for (int j = 0; j < 7; j++) {
                MyUser user = lists.get(i-1);
                if(user.getUserName()==null){
                    continue;
                }
                HSSFCell cell2 = nextRow.createCell(j);
                if (j == 0) {
                    cell2.setCellValue(user.getLoginUser());
                }
                if (j == 1) {
                    cell2.setCellValue(user.getUserName());
                }
                if (j == 2) {
                    cell2.setCellValue(user.getPassword());
                }
                if (j == 3) {
                    cell2.setCellValue(user.getPhone());
                }
                if (j == 4) {
                    cell2.setCellValue(user.getAddress());
                }
                if (j == 5) {
                    cell2.setCellValue(user.getEmail());
                }
                if (j == 6) {
                    String date = DateUtil.formatTimesTampDate(user.getUpdateTime());
                    cell2.setCellValue(date);
                }
            }
        }

        //注意
        // 临时创建一个文件
        File file = new File("E:/user.xls");
        try {
            file.createNewFile();
            // 打开文件流
            FileOutputStream outputStream = FileUtils.openOutputStream(file);
            workbook.write(outputStream);
            outputStream.close();
            return 1;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return -1;
    }
    // 设置列宽()
    private static void setColumnWidth(HSSFSheet sheet, int colNum) {
        for (int i = 0; i < colNum; i++) {
            int v = 0;
            v = Math.round(Float.parseFloat("15.0") * 37F);
            v = Math.round(Float.parseFloat("20.0") * 267.5F);
            sheet.setColumnWidth(i, v);
        }
    }


    @ApiOperation(value = "下载用户列表")
    @PostMapping("/downloadUser")
    public void downloadUser(HttpServletResponse response, Model model) {
        //待下载文件名
        String fileName = "user.xls";
        //设置为png格式的文件
        response.setHeader("content-type", "application/x-xls");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        byte[] buff = new byte[1024];
        //创建缓冲输入流
        BufferedInputStream bis = null;
        OutputStream outputStream = null;

        try {
            outputStream = response.getOutputStream();

            //这个路径为待下载文件的路径
            bis = new BufferedInputStream(new FileInputStream(new File("E:/" + fileName )));
            int read = bis.read(buff);

            //通过while循环写入到指定了的文件夹中
            while (read != -1) {
                outputStream.write(buff, 0, buff.length);
                outputStream.flush();
                read = bis.read(buff);
            }
        } catch ( IOException e ) {
            e.printStackTrace();
            //出现异常返回给页面失败的信息
            model.addAttribute("result","下载失败");
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String path = "E:/" + fileName;//临时创建的表格路径
        File file = new File(path);
        if(file.exists()){//文件存在删除文件
            file.delete();
        }
    }
}
